package com.tools.web.interceptor.quota;

import com.tools.common.object.Note;
import com.tools.common.thread.Timeunit;
import com.tools.middle.redis.client.JedisClusterPlus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 使用 JedisClusterPlus 客户端操作集群 Redis 实现配额限制拦截器
 * */
@Note("使用 JedisClusterPlus 客户端操作集群 Redis 实现配额限制拦截器")
public final class JedisClusterPlusQuotaManager extends AbsQuotaManager implements QuotaRedisLuaScript {

    @Note("JedisPlusCluster 操作集群 Redis 的客户端实例")
    private final JedisClusterPlus jedisClusterPlus;

    public JedisClusterPlusQuotaManager(JedisClusterPlus jedisClusterPlus, QuotaSource source) {
        super(source);
        this.jedisClusterPlus = Objects.requireNonNull(jedisClusterPlus, "操作 Redis 集群的客户端 JedisClusterPlus 不能为 null");
    }


    @Override
    protected boolean protected_checkIsAllow(QuotaLimit quotaLimit, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String action = quotaLimit.action();
        int allow = quotaLimit.allow();
        String uniqueID = super.protected_getUniqueID(quotaLimit, request, response);
        String key = super.protected_getKey(action, uniqueID);
        Long result = (Long) this.jedisClusterPlus.eval(CHECK_ALLOW, 1, key, allow);
        if(result != null && result == 1) return true;
        response.getWriter().write(super.protected_getQuotaErrorMessage(quotaLimit, uniqueID));
        return false;
    }

    @Override
    public void increaseQuota(String action, Object uniqueID, long expiration, Timeunit timeunit) {
        String key = super.protected_getKey(action, uniqueID.toString());
        long expirationSecond = Timeunit.toSecond(expiration, timeunit);
        this.jedisClusterPlus.eval(INCREASE, 1, key, expirationSecond);
    }
}
